package com.lk.security;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.*;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.lk.security.authentication.AuthenticationSuccessListener;
import com.lk.web.entity.SysPermission;
import com.lk.web.entity.SysUser;

/**
 * @description: 加载权限菜单实现类
 * @author: Aspirin
 * @create: 2020-08-22 10:48
 */
@Component
public class MenuAuthenticationSuccessListener implements AuthenticationSuccessListener {
  private static final Logger logger =
      LoggerFactory.getLogger(MenuAuthenticationSuccessListener.class);

  @Override
  public void successListener(
      HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
    Object principal = authentication.getPrincipal();
    if (principal instanceof SysUser) {
      SysUser sysUser = (SysUser) principal;
      // 过滤重组当前用户的菜单：将sysUser.permissions的权限，重组下父子关系放到子菜单集合中
      loadMenuTree(sysUser);
      logger.info("查询用户的所有权限菜单：{}", JSON.toJSONString(sysUser.getPermissions()));
    }
  }

  /**
   * 重组下父子关系放到子菜单中去
   *
   * @think 1.只获取所有的菜单,不要按钮 2.将这些菜单对应的子菜单封装到指定菜单的子集合里面
   * @param sysUser 用户信息
   */
  private void loadMenuTree(SysUser sysUser) {
    // permissions 用户权限
    List<SysPermission> permissions = sysUser.getPermissions();
    if (permissions == null) {
      return;
    }
    // 1. 获取所有的菜单,不要按钮
    List<SysPermission> menuList = new ArrayList<>();
    for (SysPermission p : permissions) {
      if (p.getType().equals(1)) {
        menuList.add(p);
      }
    }
    // 2.收集每个菜单的子菜单传入到对应的 children 集合中
    buildChildren(menuList);
    // 返回值: 只要获取所有根菜单(一级菜单) 即可, 因为根菜单中已经在上面收集了子菜单
    List<SysPermission> result = new ArrayList<>();
    for (SysPermission menu : menuList) {
      // 判断是否为根菜单
      if (menu.getParentId().equals(0L)) {
        // 父id为0表示根菜单
        result.add(menu);
      }
    }
    // 重新设置到 permissions 集合中
    sysUser.setPermissions(result);
  }

  /**
   * 获取子菜单
   *
   * @param menuList 菜单集合
   */
  private void buildChildren(List<SysPermission> menuList) {
    for (SysPermission menu : menuList) {
      List<SysPermission> childMenu = new ArrayList<>();
      List<String> childUrl = new ArrayList<>();
      // 获取每个菜单(menuList) 下的子菜单（menu）
      for (SysPermission p : menuList) {
        if (menu.getId().equals(p.getParentId())) {
          childMenu.add(p);
          childUrl.add(p.getUrl());
        }
      }
      // 设置子菜单
      menu.setChildren(childMenu);
      menu.setChildrenUrl(childUrl);
    }
  }
}
